#include <iostream>
#include <cstring>
#include <dirent.h> /* 可以控制文件夹和目录 */  /* 文件解析第一步 */
#include "LinkTree.h"
//无序树

/* 回调函数中被调用的函数 */
void showString(void* element)
{
    std::cout<<(char*)element<<std::endl;
}

bool IsStringEqual(void * p1,void *p2)
{
    return strcmp((char*)p1,(char*)p2) == 0;//相等则为0，bool则为true
}

/* 扫描文件夹 */
void ExploreDirectory(const std::string& path,Node * node)   //path路径,传输的节点 
{
    //打开文件夹
    DIR* dir = opendir(path.c_str());    //文件夹结构体只能定义指针不能定义对象，因为头文件里只有声明
    if(dir == nullptr)
    {
        std::cout<<"文件夹路径有问题\n";
        return;
    }

    //读取文件夹的文件内容
    struct dirent *e = nullptr; //dirent文件信息结构体
    while((e = readdir(dir)) != nullptr)  //不为空则继续读
    {
        //std::cout<<e->d_name<<" "<<(int)e->d_type<<std::endl;

        if(strcmp(e->d_name,".") == 0 || strcmp(e->d_name,"..") == 0)//过滤.和..
        {
            continue;   //跳转至while循环的测试条件
        }
        Node *fileNode = new Node(strdup(e->d_name));   //把文件名传进去变成一个节点 //strdup可以把e->d_name放在堆上
        fileNode->Connect(node);    //传过来的是node = root连到根root
        
        if(e->d_type == 4)//如果里面还有文件夹，继续展开遍历
        {
            ExploreDirectory(path + "/" + std::string(e->d_name),fileNode);//传入路径名称（路径就是拼字符串），接在当前路径下
        }
    }

    //关闭文件夹
    closedir(dir);
}

int main(int argc,char * argv[])
{
    // ExploreDirectory("./");
/* 给路径，展开文件 */
    std::string path = argc < 2 ? "./" : argv[1];//argc默认./
    LinkTree tree;
    Node *rootNode = new Node(strdup(path.c_str()));
    rootNode->Connect(tree.GetRoot());
    ExploreDirectory(path,rootNode);
    tree.SetShowtype(showString);
    tree.show();
    
/* 给文件名，拼出路径 */
    std::string FileName;
    std::cin>>FileName;
    tree.SetFindType(IsStringEqual);    //调用函数！
    Node * target = tree.FindNode((void*)FileName.c_str()); //找到节点
    std::string pwd;
    while(target->GetParent() != nullptr)   //找到根目录停止
    {
        pwd = std::string((char*)target->GetData()) + "/" + pwd; 
        target = target->GetParent();   //继续往上走
    }
    pwd.erase(pwd.size() - 1);
    std::cout<<pwd<<std::endl;
    return 0;
}
    // Node *class1 = new Node((void*)"259班");
    // Node *class2 = new Node((void*)"262班");

    // class1->Connect(tree.GetRoot());    
    // class2->Connect(tree.GetRoot());

    // Node * stu1 = new Node((void*)"张三");  
    // Node * stu2 = new Node((void*)"李四");
    // Node * stu3 = new Node((void*)"王五");

    // stu1->Connect(class1);  //接到class
    // stu2->Connect(class2);
    // stu3->Connect(class2);

    //tree.SetShowtype(showString);
    // //tree.show();

    // tree.SetFindType(IsStringEqual);
    // Node *n = tree.FindNode((void*)"李四");
    // if(n)
    // {
    //     n->DisConnect();
    // }
    // n->Connect(tree.FindNode((void*)"262班"));//连接位置也需要找
    // tree.show();



    // Node * n1 = new Node(1);
    // Node * n2 = new Node(2);
    // Node * n3 = new Node(3);
    // Node * n4 = new Node(4);

    // n1->Connect(tree.GetRoot());
    // n2->Connect(n1);
    // n3->Connect(n1);
    // n4->Connect(n3);

    // tree.show();
    // //std::cout<<tree.GetTreeHeight()<<std::endl;

    // // n1->TravelNode(n1);

    // Node * n = tree.FindNode(3);
    // printf("%p %p\n",n,n3);//打印地址进行比较，判断地址是否相同
    

